home *** CD-ROM | disk | FTP | other *** search
- /*
- * Routines to read a data base of run-time information.
- */
- #include <ctype.h>
- #include "../h/gsupport.h"
- #include "../h/version.h"
-
- #define GetInt(n, c)\
- n = 0;\
- while (isdigit(c)) {\
- n = n * 10 + (c - '0');\
- c = getc(db);\
- }
-
- #define SkipWhSp(c)\
- while (isspace(c)) {\
- if (c == '\n')\
- ++dbline;\
- c = getc(db);\
- }
-
- /*
- * prototypes for static functions.
- */
- hidden int cmp_1_pre Params((int p1, int p2));
- hidden struct il_code *db_abstr Params((noargs));
- hidden novalue db_case Params((struct il_code *il, int num_cases));
- hidden novalue db_err3 Params((int fatal,char *s1,char *s2,char *s3));
- hidden int db_icntyp Params((noargs));
- hidden struct il_c *db_ilc Params((noargs));
- hidden struct il_c *db_ilcret Params((int il_c_type));
- hidden struct il_code *db_inlin Params((noargs));
- hidden struct il_code *db_ilvar Params((noargs));
- hidden int db_rtflg Params((noargs));
- hidden int db_tndtyp Params((noargs));
- hidden struct il_c *new_ilc Params((int il_c_type));
- hidden novalue quoted Params((int delim));
-
- extern char *progname;
-
- static char *dbname;
- static FILE *db;
- static int dbline;
- static struct str_buf db_sbuf;
-
- /*
- * opendb - open data base and do other house keeping.
- */
- int db_open(s, lrgintflg)
- char *s;
- char **lrgintflg;
- {
- char *msg_buf;
- static int first_time = 1;
-
- if (first_time) {
- first_time = 0;
- init_sbuf(&db_sbuf);
- }
- dbname = s;
- dbline = 0;
- *lrgintflg = NULL;
- db = fopen(dbname, "r");
- if (db == NULL)
- return 0;
- ++dbline;
- s = db_string();
- if (strcmp(s, DVersion) != 0) {
- msg_buf = (char *)alloc((unsigned int) 35 + (int)(strlen(s) +
- strlen(progname) + strlen(DVersion)));
- sprintf(msg_buf, "found version %s, %s requires version %s",
- s, progname, DVersion);
- db_err1(1, msg_buf);
- }
- *lrgintflg = db_string();
- return 1;
- }
-
- novalue db_close()
- {
- fclose(db);
- }
-
- char *db_string()
- {
- register int c;
-
- /*
- * Look for the start of the string; '$' starts a special indicator.
- * Copy characters into string buffer until white space is found.
- */
- c = getc(db);
- SkipWhSp(c);
- if (c == EOF)
- db_err1(1, "unexpeced EOF");
- if (c == '$')
- return NULL;
- while (!isspace(c) && c != EOF) {
- AppChar(db_sbuf, c);
- c = getc(db);
- }
- if (c == '\n')
- ++dbline;
- return str_install(&db_sbuf);
- }
-
- /*
- * db_impl reads basic implementation information into a structure and
- * returns it.
- */
- struct implement *db_impl(oper_typ)
- int oper_typ;
- {
- register struct implement *ip;
- register int c;
- int i;
- char *name;
- long n;
-
- if ((name = db_string()) == NULL)
- return NULL;
-
- ip = NewStruct(implement);
- ip->blink = NULL;
- ip->iconc_flgs = 0; /* reserved for internal use by compiler */
- ip->oper_typ = oper_typ;
- ip->name = name;
- ip->op = NULL;
-
- c = getc(db);
- SkipWhSp(c)
- if (isalpha(c) || isdigit(c))
- ip->prefix[0] = c;
- else
- db_err2(1, "invalid prefix for", ip->name);
- c = getc(db);
- if (isalpha(c) || isdigit(c))
- ip->prefix[1] = c;
- else
- db_err2(1, "invalid prefix for", ip->name);
- c = getc(db);
- SkipWhSp(c)
- if (!isdigit(c))
- db_err2(1, "number of parameters missing for", ip->name);
- GetInt(n, c)
- ip->nargs = n;
- if (n == 0)
- ip->arg_flgs = NULL;
- else
- ip->arg_flgs = (int *)alloc((unsigned int) (sizeof(int) * n));
- if (c != '(')
- db_err2(1, "parameter flags missing for", ip->name);
- c = getc(db);
- for (i = 0; i < n; ++i) {
- if (c == ',' || c == ')')
- db_err2(1, "parameter flag missing for", ip->name);
- ip->arg_flgs[i] = 0;
- while (c != ',' && c != ')') {
- switch (c) {
- case 'u':
- ip->arg_flgs[i] |= RtParm;
- break;
- case 'd':
- ip->arg_flgs[i] |= DrfPrm;
- break;
- case 'v':
- ip->arg_flgs[i] |= VarPrm;
- break;
- default:
- db_err2(1, "invalid parameter flag for", ip->name);
- }
- c = getc(db);
- }
- if (c == ',')
- c = getc(db);
- }
- if (c != ')')
- db_err2(1, "invalid parameter flag list for", ip->name);
- c = getc(db);
- SkipWhSp(c)
- if (c != '{')
- db_err2(1, "result sequence missing for", ip->name);
- c = getc(db);
- ip->resume = 0;
- if (c == '}') {
- ip->min_result = NoRsltSeq;
- ip->max_result = NoRsltSeq;
- }
- else {
- if (!isdigit(c))
- db_err2(1, "invalid result sequence for", ip->name);
- GetInt(n, c)
- ip->min_result = n;
- if (c != ',')
- db_err2(1, "invalid result sequence for", ip->name);
- c = getc(db);
- if (c == '*') {
- ip->max_result = UnbndSeq;
- c = getc(db);
- }
- else if (isdigit(c)) {
- GetInt(n, c)
- ip->max_result = n;
- }
- else
- db_err2(1, "invalid result sequence for", ip->name);
- if (c == '+') {
- ip->resume = 1;
- c = getc(db);
- }
- if (c != '}')
- db_err2(1, "invalid result sequence for", ip->name);
- }
- ip->ret_flag = db_rtflg();
- c = getc(db);
- SkipWhSp(c)
- switch (c) {
- case 't':
- ip->use_rslt = 1;
- break;
- case 'f':
- ip->use_rslt = 0;
- break;
- default:
- db_err2(1, "invalid 'result' use indicator for", ip->name);
- }
- return ip;
- }
-
- /*
- * db_code - read the in-line code for an operation.
- */
- novalue db_code(ip)
- struct implement *ip;
- {
- register int c;
- char *s;
- word n;
- int var_type;
- int i;
-
- /*
- * read the descriptive string.
- */
- c = getc(db);
- SkipWhSp(c)
- if (c != '"')
- db_err1(1, "operation description expected");
- for (c = getc(db); c != '"' && c != '\n' && c != EOF; c = getc(db)) {
- if (c == '\\') {
- AppChar(db_sbuf, c);
- c = getc(db);
- }
- AppChar(db_sbuf, c);
- }
- if (c != '"')
- db_err1(1, "expected '\"'");
- ip->comment = str_install(&db_sbuf);
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c)
- ip->ntnds = n;
- if (n == 0)
- ip->tnds = NULL;
- else
- ip->tnds = (struct tend_var *)alloc((unsigned int)
- (sizeof(struct tend_var) * n));
- for (i = 0; i < n; ++i) {
- var_type = db_tndtyp();
- ip->tnds[i].var_type = var_type;
- ip->tnds[i].blk_name = NULL;
- if (var_type == TndBlk) {
- s = db_string();
- if (s == NULL)
- db_err1(1, "block name expected");
- if (*s != '*')
- ip->tnds[i].blk_name = s;
- }
- ip->tnds[i].init = db_ilc();
- }
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c)
- ip->nvars = n;
- if (n == 0)
- ip->vars = NULL;
- else
- ip->vars = (struct ord_var *)alloc((unsigned int)
- (sizeof(struct ord_var) * n));
- for (i = 0; i < n; ++i) {
- s = db_string();
- if (s == NULL)
- db_err1(1, "variable name expected");
- ip->vars[i].name = s;
- ip->vars[i].dcl = db_ilc();
- }
- ip->in_line = db_inlin();
- c = getc(db);
- SkipWhSp(c)
- if (c != '$')
- db_err1(1, "expected $end");
- }
-
- /*
- * db_inlin - read in the in-line code for an operation.
- */
- static struct il_code *db_inlin()
- {
- struct il_code *il;
- register int c;
- int i;
- int indx;
- int n, n1;
-
- c = getc(db);
- SkipWhSp(c)
- switch (c) {
- case 'a':
- db_chstr("a", "bstr");
- il = new_il(IL_Abstr, 2);
- il->u[0].fld = db_abstr();
- il->u[1].fld = db_abstr();
- break;
-
- case 'b':
- db_chstr("b", "lock");
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c) /* number of local tended */
- il = new_il(IL_Block, 2 + n);
- il->u[0].n = n;
- for (i = 1; i <= n; ++i)
- il->u[i].n = db_tndtyp();
- il->u[i].c_cd = db_ilc(); /* body of block */
- break;
-
- case 'c':
- switch (getc(db)) {
- case 'a': {
- char prfx3;
- int ret_val;
- int ret_flag;
- int rslt;
- int num_sbuf;
- int num_cbuf;
-
- db_chstr("ca", "ll");
- c = getc(db);
- SkipWhSp(c)
- prfx3 = c;
- c = getc(db);
- SkipWhSp(c)
- switch (c) {
- case 'i':
- ret_val = RetInt;
- break;
- case 'd':
- ret_val = RetDbl;
- break;
- case 'n':
- ret_val = RetNoVal;
- break;
- case 's':
- ret_val = RetSig;
- break;
- default:
- db_err1(1, "invalid indicator for type of return value");
- }
- c = getc(db);
- ret_flag = db_rtflg();
- c = getc(db);
- SkipWhSp(c)
- switch (c) {
- case 't':
- rslt = 1;
- break;
- case 'f':
- rslt = 0;
- break;
- default:
- db_err1(1, "t or f expected");
- }
- c = getc(db);
- SkipWhSp(c)
- GetInt(num_sbuf, c)
- c = getc(db);
- SkipWhSp(c)
- GetInt(num_cbuf, c)
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c) /* num args */
- il = new_il(IL_Call, 8 + n * 2);
- il->u[0].n = 0; /* reserved for internal use by compiler */
- il->u[1].n = prfx3;
- il->u[2].n = ret_val;
- il->u[3].n = ret_flag;
- il->u[4].n = rslt;
- il->u[5].n = num_sbuf;
- il->u[6].n = num_cbuf;
- il->u[7].n = n;
- indx = 8;
- /*
- * get the prototype parameter declarations and actual arguments.
- */
- n *= 2;
- while (n--)
- il->u[indx++].c_cd = db_ilc();
- }
- break;
-
- case 'n':
- if (getc(db) != 'v')
- db_err1(1, "expected cnv1 or cnv2");
- switch (getc(db)) {
- case '1':
- il = new_il(IL_Cnv1, 2);
- il->u[0].n = db_icntyp(); /* type code */
- il->u[1].fld = db_ilvar(); /* source */
- break;
- case '2':
- il = new_il(IL_Cnv2, 3);
- il->u[0].n = db_icntyp(); /* type code */
- il->u[1].fld = db_ilvar(); /* source */
- il->u[2].c_cd = db_ilc(); /* destination */
- break;
- default:
- db_err1(1, "expected cnv1 or cnv2");
- }
- break;
-
- case 'o':
- db_chstr("co", "nst");
- il = new_il(IL_Const, 2);
- il->u[0].n = db_icntyp(); /* type code */
- c = getc(db);
- SkipWhSp(c)
- if (c == '"' || c == '\'') {
- quoted(c);
- c = getc(db);
- }
- else
- while (c != EOF && !isspace(c)) {
- AppChar(db_sbuf, c);
- c = getc(db);
- }
- il->u[1].s = str_install(&db_sbuf);
- break;
-
- default:
- db_err1(1, "expected call, const, cnv1, or cnv2");
- }
- break;
-
- case 'd':
- if (getc(db) != 'e' || getc(db) != 'f')
- db_err1(1, "expected def1 or def2");
- switch (getc(db)) {
- case '1':
- il = new_il(IL_Def1, 3);
- il->u[0].n = db_icntyp(); /* type code */
- il->u[1].fld = db_ilvar(); /* source */
- il->u[2].c_cd = db_ilc(); /* default value */
- break;
- case '2':
- il = new_il(IL_Def2, 4);
- il->u[0].n = db_icntyp(); /* type code */
- il->u[1].fld = db_ilvar(); /* source */
- il->u[2].c_cd = db_ilc(); /* default value */
- il->u[3].c_cd = db_ilc(); /* destination */
- break;
- default:
- db_err1(1, "expected dflt1 or dflt2");
- }
- break;
-
- case 'r':
- if (getc(db) != 'u' || getc(db) != 'n' || getc(db) != 'e' ||
- getc(db) != 'r' || getc(db) != 'r')
- db_err1(1, "expected runerr1 or runerr2");
- switch (getc(db)) {
- case '1':
- il = new_il(IL_Err1, 1);
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c)
- il->u[0].n = n; /* error number */
- break;
- case '2':
- il = new_il(IL_Err2, 2);
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c)
- il->u[0].n = n; /* error number */
- il->u[1].fld = db_ilvar(); /* variable */
- break;
- default:
- db_err1(1, "expected runerr1 or runerr2");
- }
- break;
-
- case 'i':
- switch (getc(db)) {
- case 'f':
- switch (getc(db)) {
- case '1':
- il = new_il(IL_If1, 2);
- il->u[0].fld = db_inlin(); /* condition */
- il->u[1].fld = db_inlin(); /* then clause */
- break;
- case '2':
- il = new_il(IL_If2, 3);
- il->u[0].fld = db_inlin(); /* condition */
- il->u[1].fld = db_inlin(); /* then clause */
- il->u[2].fld = db_inlin(); /* else clause */
- break;
- default:
- db_err1(1, "expected if1 or if2");
- }
- break;
- case 's':
- il = new_il(IL_Is, 2);
- il->u[0].n = db_icntyp(); /* type code */
- il->u[1].fld = db_ilvar(); /* variable */
- break;
- default:
- db_err1(1, "expected if1, if2, or is");
- }
- break;
-
- case 'l':
- switch (getc(db)) {
- case 'c':
- db_chstr("lc", "ase");
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c) /* number of cases */
- il = new_il(IL_Lcase, 2 + 2 * n);
- il->u[0].n = n;
- indx = 1;
- while (n--) {
- c = getc(db);
- SkipWhSp(c)
- GetInt(n1, c)
- il->u[indx++].n = n1; /* selection number */
- il->u[indx++].fld = db_inlin(); /* action */
- }
- il->u[indx].fld = db_inlin(); /* default */
- break;
-
- case 's':
- if (getc(db) != 't')
- db_err1(1, "expected lst");
- il = new_il(IL_Lst, 2);
- il->u[0].fld = db_inlin();
- il->u[1].fld = db_inlin();
- break;
-
- default:
- db_err1(1, "expected lcase or lst");
- }
- break;
-
- case 'n':
- db_chstr("n", "il");
- il = NULL;
- break;
-
- case 't': {
- struct il_code *var;
-
- if (getc(db) != 'c' || getc(db) != 'a' || getc(db) != 's' ||
- getc(db) != 'e')
- db_err1(1, "expected tcase1 or tcase2");
- switch (getc(db)) {
- case '1':
- var = db_ilvar(); /* variable */
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c)
- il = new_il(IL_Tcase1, 3 * n + 2);
- il->u[0].fld = var;
- db_case(il, n);
- break;
-
- case '2':
- var = db_ilvar(); /* variable */
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c)
- il = new_il(IL_Tcase2, 3 * n + 3);
- il->u[0].fld = var;
- db_case(il, n);
- il->u[3 * n + 2].fld = db_inlin(); /* default */
- break;
-
- default:
- db_err1(1, "expected tcase1 or tcase2");
- }
- }
- break;
-
- case '!':
- il = new_il(IL_Bang, 1);
- il->u[0].fld = db_inlin();
- break;
-
- case '&':
- if (getc(db) != '&')
- db_err1(1, "expected &&");
- il = new_il(IL_And, 2);
- il->u[0].fld = db_inlin();
- il->u[1].fld = db_inlin();
- break;
-
- default:
- db_err1(1, "syntax error");
- }
- return il;
- }
-
- static int db_rtflg()
- {
- register int c;
- int ret_flag;
-
- ret_flag = 0;
- c = getc(db);
- SkipWhSp(c)
- if (c == 'f')
- ret_flag |= DoesFail;
- else if (c != '_')
- db_err1(1, "invalid return indicator");
- c = getc(db);
- if (c == 'r')
- ret_flag |= DoesRet;
- else if (c != '_')
- db_err1(1, "invalid return indicator");
- c = getc(db);
- if (c == 's')
- ret_flag |= DoesSusp;
- else if (c != '_')
- db_err1(1, "invalid return indicator");
- c = getc(db);
- if (c == 'e')
- ret_flag |= DoesEFail;
- else if (c != '_')
- db_err1(1, "invalid return indicator");
- c = getc(db);
- if (c == 't')
- ret_flag |= DoesFThru;
- else if (c != '_' && c != ' ')
- db_err1(1, "invalid return indicator");
- return ret_flag;
- }
-
- static novalue db_case(il, num_cases)
- struct il_code *il;
- int num_cases;
- {
- register int c;
- int *typ_vect;
- int i, j;
- int num_types;
- int indx;
-
- il->u[1].n = num_cases;
- indx = 2;
- for (i = 0; i < num_cases; ++i) {
- c = getc(db);
- SkipWhSp(c)
- GetInt(num_types, c)
- il->u[indx++].n = num_types;
- typ_vect = (int *)alloc((unsigned int)(sizeof(int) * num_types));
- il->u[indx++].vect = typ_vect;
- for (j = 0; j < num_types; ++j)
- typ_vect[j] = db_icntyp(); /* type code */
- il->u[indx++].fld = db_inlin(); /* action */
- }
- }
-
- static struct il_code *db_ilvar()
- {
- struct il_code *il;
- register int c;
- int n;
-
- c = getc(db);
- SkipWhSp(c)
-
- if (isdigit(c)) {
- il = new_il(IL_Var, 1);
- GetInt(n, c)
- il->u[0].n = n; /* symbol table index */
- }
- else {
- if (c != '[')
- db_err1(1, "expected symbol table index or '['");
- il = new_il(IL_Subscr, 2);
- c = getc(db);
- SkipWhSp(c);
- GetInt(n, c)
- il->u[0].n = n; /* symbol table index */
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c)
- il->u[1].n = n; /* subscripting index */
- }
- return il;
- }
-
- static struct il_code *db_abstr()
- {
- struct il_code *il;
- register int c;
- word typcd;
- word indx;
- int nargs;
-
- c = getc(db);
- SkipWhSp(c)
- switch (c) {
- case 'f':
- db_chstr("f", "lds");
- il = new_il(IL_Fields, 1);
- il->u[0].fld = db_abstr(); /* record type */
- break;
-
- case 'l':
- if (getc(db) != 's' || getc(db) != 't')
- db_err1(1, "expected lst or lstelm");
- switch (getc(db)) {
- case ' ':
- case '\t':
- case '\n':
- il = new_il(IL_Lst, 2);
- il->u[0].fld = db_abstr();
- il->u[1].fld = db_abstr();
- break;
- case 'e':
- db_chstr("lste", "lm");
- il = new_il(IL_LstElm, 1);
- il->u[0].fld = db_abstr(); /* list type */
- break;
- default:
- db_err1(1, "expected lst or lstelm");
- }
- break;
-
- case 'n':
- switch (getc(db)) {
- case 'e':
- if (getc(db) != 'w')
- db_err1(1, "expected new");
- typcd = db_icntyp();
- c = getc(db);
- SkipWhSp(c)
- GetInt(nargs, c)
- il = new_il(IL_New, 2 + nargs);
- il->u[0].n = typcd;
- il->u[1].n = nargs;
- indx = 2;
- while (nargs--)
- il->u[indx++].fld = db_abstr();
- break;
- case 'i':
- if (getc(db) != 'l')
- db_err1(1, "expected nil");
- il = NULL;
- break;
- default:
- db_err1(1, "expected new or nil");
- }
- break;
-
- case 's':
- switch (getc(db)) {
- case 'e':
- db_chstr("se", "telm");
- il = new_il(IL_SetElm, 1);
- il->u[0].fld = db_abstr(); /* set type */
- break;
- case 't':
- switch (getc(db)) {
- case 'o':
- db_chstr("sto", "re");
- il = new_il(IL_Store, 1);
- il->u[0].fld = db_abstr(); /* type to "dereference" */
- break;
- case 'r':
- db_chstr("str", "var");
- il = new_il(IL_StrVar, 1);
- il->u[0].fld = db_abstr(); /* substring variable type */
- break;
- default:
- db_err1(1, "expected store or strvar");
- }
- break;
- default:
- db_err1(1, "expected setelm, store, or strvar");
- }
- break;
-
- case 't':
- switch (getc(db)) {
- case 'b':
- if (getc(db) != 'l')
- db_err1(1, "expected tbldf, tblelm, or tblkey");
- switch (getc(db)) {
- case 'd':
- db_chstr("tbld", "ft");
- il = new_il(IL_TblDft, 1);
- il->u[0].fld = db_abstr(); /* table type */
- break;
- case 'e':
- db_chstr("tble", "lm");
- il = new_il(IL_TblElm, 1);
- il->u[0].fld = db_abstr(); /* table type */
- break;
- case 'k':
- db_chstr("tblk", "ey");
- il = new_il(IL_TblKey, 1);
- il->u[0].fld = db_abstr(); /* table type */
- break;
- default:
- db_err1(1, "expected tbldf, tblelm, or tblkey");
- }
- break;
- case 'r':
- db_chstr("tr", "ptbl");
- il = new_il(IL_TrpTbl, 1);
- il->u[0].fld = db_abstr(); /* table trapped variable type */
- break;
- case 'y':
- if (getc(db) != 'p')
- db_err1(1, "expected typ");
- il = new_il(IL_IcnTyp, 1);
- il->u[0].n = db_icntyp(); /* type code */
- break;
- default:
- db_err1(1, "expected tbldft, tblelm, tblkey, or typ");
- }
- break;
-
- case 'v':
- db_chstr("v", "artyp");
- il = new_il(IL_VarTyp, 1);
- il->u[0].fld = db_ilvar(); /* variable */
- break;
-
- case '=':
- il = new_il(IL_TpAsgn, 2);
- il->u[0].fld = db_abstr();
- il->u[1].fld = db_abstr();
- break;
-
- case '+':
- if (getc(db) != '+')
- db_err1(1, "expected ++");
- il = new_il(IL_Union, 2);
- il->u[0].fld = db_abstr();
- il->u[1].fld = db_abstr();
- break;
-
- case '*':
- if (getc(db) != '*')
- db_err1(1, "expected **");
- il = new_il(IL_Inter, 2);
- il->u[0].fld = db_abstr();
- il->u[1].fld = db_abstr();
- break;
- }
- return il;
- }
-
- /*
- * db_ilc - read a piece of in-line C code.
- */
- static struct il_c *db_ilc()
- {
- register int c;
- int old_c;
- word n;
- struct il_c *base = NULL;
- struct il_c **nxtp = &base;
-
- c = getc(db);
- SkipWhSp(c)
- switch (c) {
- case '$':
- /*
- * This had better be the starting $c.
- */
- c = getc(db);
- if (c == 'c') {
- c = getc(db);
- for (;;) {
- SkipWhSp(c)
- if (c == '$') {
- c = getc(db);
- switch (c) {
- case 'c': /* $cb or $cgoto <cond> <lbl num> */
- c = getc(db);
- switch (c) {
- case 'b':
- *nxtp = new_ilc(ILC_CBuf);
- c = getc(db);
- break;
- case 'g':
- db_chstr("$cg", "oto");
- *nxtp = new_ilc(ILC_CGto);
- (*nxtp)->code[0] = db_ilc();
- c = getc(db);
- SkipWhSp(c);
- if (!isdigit(c))
- db_err1(1, "$cgoto: expected label number");
- GetInt(n, c);
- (*nxtp)->n = n;
- break;
- default:
- db_err1(1, "expected $cb or $cgoto");
- }
- break;
- case 'e':
- c = getc(db);
- if (c == 'f') { /* $efail */
- db_chstr("$ef", "ail");
- *nxtp = new_ilc(ILC_EFail);
- c = getc(db);
- break;
- }
- else
- return base; /* $e */
- case 'f': /* $fail */
- db_chstr("$f", "ail");
- *nxtp = new_ilc(ILC_Fail);
- c = getc(db);
- break;
- case 'g': /* $goto <lbl num> */
- db_chstr("$g", "oto");
- *nxtp = new_ilc(ILC_Goto);
- c = getc(db);
- SkipWhSp(c);
- if (!isdigit(c))
- db_err1(1, "$goto: expected label number");
- GetInt(n, c);
- (*nxtp)->n = n;
- break;
- case 'l': /* $lbl <lbl num> */
- db_chstr("$l", "bl");
- *nxtp = new_ilc(ILC_Lbl);
- c = getc(db);
- SkipWhSp(c);
- if (!isdigit(c))
- db_err1(1, "$lbl: expected label number");
- GetInt(n, c);
- (*nxtp)->n = n;
- break;
- case 'm': /* $m[d]<indx> */
- *nxtp = new_ilc(ILC_Mod);
- c = getc(db);
- if (c == 'd') {
- (*nxtp)->s = "d";
- c = getc(db);
- }
- if (isdigit(c)) {
- GetInt(n, c);
- (*nxtp)->n = n;
- }
- else if (c == 'r') {
- (*nxtp)->n = RsltIndx;
- c = getc(db);
- }
- else
- db_err1(1, "$m: expected symbol table index");
- break;
- case 'r': /* $r[d]<indx> or $ret ... */
- c = getc(db);
- if (isdigit(c) || c == 'd') {
- *nxtp = new_ilc(ILC_Ref);
- if (c == 'd') {
- (*nxtp)->s = "d";
- c = getc(db);
- }
- GetInt(n, c);
- (*nxtp)->n = n;
- }
- else if (c == 'r') {
- *nxtp = new_ilc(ILC_Ref);
- (*nxtp)->n = RsltIndx;
- c = getc(db);
- }
- else {
- if (c != 'e' || getc(db) != 't')
- db_err1(1, "expected $ret");
- *nxtp = db_ilcret(ILC_Ret);
- c = getc(db);
- }
- break;
- case 's': /* $sb or $susp ... */
- c = getc(db);
- switch (c) {
- case 'b':
- *nxtp = new_ilc(ILC_SBuf);
- c = getc(db);
- break;
- case 'u':
- db_chstr("$su", "sp");
- *nxtp = db_ilcret(ILC_Susp);
- c = getc(db);
- break;
- default:
- db_err1(1, "expected $sb or $susp");
- }
- break;
- case 't': /* $t[d]<indx> */
- *nxtp = new_ilc(ILC_Tend);
- c = getc(db);
- if (!isdigit(c))
- db_err1(1, "$t: expected index");
- GetInt(n, c);
- (*nxtp)->n = n;
- break;
- case '{':
- *nxtp = new_ilc(ILC_LBrc);
- c = getc(db);
- break;
- case '}':
- *nxtp = new_ilc(ILC_RBrc);
- c = getc(db);
- break;
- default:
- db_err1(1, "invalid $ escape in C code");
- }
- }
- else {
- /*
- * Arbitrary code - gather into a string.
- */
- while (c != '$' && c != EOF) {
- if (c == '"' || c == '\'') {
- quoted(c);
- c = getc(db);
- }
- old_c = c;
- AppChar(db_sbuf, c);
- c = getc(db);
- if (old_c == ' ')
- while (c == ' ')
- c = getc(db);
- }
- *nxtp = new_ilc(ILC_Str);
- (*nxtp)->s = str_install(&db_sbuf);
- }
- nxtp = &(*nxtp)->next;
- }
- }
- break;
- case 'n':
- db_chstr("n", "il");
- return NULL;
- }
- db_err1(1, "expected C code of the form $c ... $e or nil");
- }
-
- static novalue quoted(delim)
- int delim;
- {
- register int c;
-
- AppChar(db_sbuf, delim);
- c = getc(db);
- while (c != delim && c != EOF) {
- if (c == '\\') {
- AppChar(db_sbuf, c);
- c = getc(db);
- if (c == EOF)
- db_err1(1, "unexpected EOF in quoted literal");
- }
- AppChar(db_sbuf, c);
- c = getc(db);
- }
- if (c == EOF)
- db_err1(1, "unexpected EOF in quoted literal");
- AppChar(db_sbuf, c);
- }
-
- static struct il_c *db_ilcret(il_c_type)
- int il_c_type;
- {
- struct il_c *ilc;
- int c;
- int n;
- int i;
-
- ilc = new_ilc(il_c_type);
- ilc->n = db_icntyp();
- c = getc(db);
- SkipWhSp(c)
- GetInt(n, c)
- for (i = 0; i < n; ++i)
- ilc->code[i] = db_ilc();
- return ilc;
- }
-
- static int db_tndtyp()
- {
- int c;
-
- c = getc(db);
- SkipWhSp(c)
- switch (c) {
- case 'b':
- db_chstr("b", "lkptr");
- return TndBlk;
- case 'd':
- db_chstr("d", "esc");
- return TndDesc;
- case 's':
- db_chstr("s", "tr");
- return TndStr;
- default:
- db_err1(1, "expected blkptr, desc, or str");
- /* NOTREACHED */
- }
- }
-
- static int db_icntyp()
- {
- int c;
-
- c = getc(db);
- SkipWhSp(c)
- switch (c) {
- case 'c':
- switch (getc(db)) {
- case 'i':
- return TypCInt;
- case 'd':
- return TypCDbl;
- case 's':
- return TypCStr;
- case ' ':
- case '\n':
- case '\t':
- return TypCset;
- }
- break;
- case 'd':
- return RetDesc;
- case 'e':
- switch (getc(db)) {
- case 'c':
- if (getc(db) == 'i')
- return TypECInt;
- break;
- case 'i':
- return TypEInt;
- case ' ':
- case '\n':
- case '\t':
- return TypEmpty;
- }
- break;
- case 'f':
- return TypFile;
- case 'i':
- return TypInt;
- case 'k':
- switch (getc(db)) {
- case 'i':
- return TypKyInt;
- case 's':
- return TypKySub;
- case 'p':
- return TypKyPos;
- }
- break;
- case 'n':
- switch (getc(db)) {
- case 'v':
- return RetNVar;
- case ' ':
- case '\n':
- case '\t':
- return TypNull;
- }
- break;
- case 'p':
- return TypProc;
- case 'r':
- switch (getc(db)) {
- case 'n':
- return RetNone;
- case ' ':
- case '\n':
- case '\t':
- return TypReal;
- }
- break;
- case 's':
- switch (getc(db)) {
- case 's':
- return TypTvStr;
- case 'v':
- return RetSVar;
- case ' ':
- case '\n':
- case '\t':
- return TypStr;
- }
- break;
- case 't':
- switch (getc(db)) {
- case 'c':
- return TypTCset;
- case 's':
- return TypTStr;
- case 't':
- return TypTvTbl;
- }
- break;
- case 'v':
- return TypVar;
- case 'C':
- return TypCoExp;
- case 'L':
- return TypList;
- case 'R':
- return TypRec;
- case 'S':
- return TypSet;
- case 'T':
- return TypTbl;
- }
- db_err1(1, "invalid type code");
- /* NOTREACHED */
- }
-
- static struct il_c *new_ilc(il_c_type)
- int il_c_type;
- {
- struct il_c *ilc;
- int i;
-
- ilc = NewStruct(il_c);
- ilc->next = NULL;
- ilc->il_c_type = il_c_type;
- for (i = 0; i < 3; ++i)
- ilc->code[i] = NULL;
- ilc->n = 0;
- ilc->s = NULL;
- return ilc;
- }
-
- struct il_code *new_il(il_type, size)
- int il_type;
- int size;
- {
- struct il_code *il;
-
- il = (struct il_code *)alloc((unsigned int)
- (sizeof(struct il_code) + (size-1) * sizeof(union il_fld)));
- il->il_type = il_type;
- return il;
- }
-
- /*
- * db_dscrd - discard an implementation, skipping the in-line code.
- */
- novalue db_dscrd(ip)
- struct implement *ip;
- {
- char state; /* how far along we are at recognizing $end */
-
- free(ip);
- state = '\0';
- for (;;) {
- switch (getc(db)) {
- case '$':
- state = '$';
- continue;
- case 'e':
- if (state == '$') {
- state = 'e';
- continue;
- }
- break;
- case 'n':
- if (state == 'e') {
- state = 'n';
- continue;
- }
- break;
- case 'd':
- if (state == 'n')
- return;
- break;
- case '\n':
- ++dbline;
- break;
- case EOF:
- db_err1(1, "unexpected EOF");
- }
- state = '\0';
- }
- }
-
- /*
- * db_chstr - we are expecting a specific string. We may already have
- * read a prefix of it.
- */
- novalue db_chstr(prefix, suffix)
- char *prefix;
- char *suffix;
- {
- int c;
-
- c = getc(db);
- SkipWhSp(c)
-
- for (;;) {
- if (*suffix == '\0' && (isspace(c) || c == EOF)) {
- if (c == '\n')
- ++dbline;
- return;
- }
- else if (*suffix != c)
- break;
- c = getc(db);
- ++suffix;
- }
- db_err3(1, "expected:", prefix, suffix);
- }
-
- /*
- * db_tbl - fill in a table of implementation information for the given section.
- */
- int db_tbl(section, tbl)
- char *section;
- struct implement **tbl;
- {
- struct implement *ip;
- int num_added = 0;
- unsigned hashval;
-
- /*
- * Get past the section header.
- */
- db_chstr("", section);
-
- while ((ip = db_impl(toupper(section[0]))) != NULL) {
- if (db_ilkup(ip->name, tbl) == NULL) {
- db_code(ip);
- hashval = IHasher(ip->name);
- ip->blink = tbl[hashval];
- tbl[hashval] = ip;
- ++num_added;
- db_chstr("", "end");
- }
- else
- db_dscrd(ip);
- }
- db_chstr("", "endsect");
- return num_added;
- }
-
- /*
- * db_ilkup looks up id in a table of implementation information and returns
- * pointer it or NULL if it is not there.
- */
- struct implement *db_ilkup(id, tbl)
- char *id;
- struct implement **tbl;
- {
- register struct implement *ptr;
-
- ptr = tbl[IHasher(id)];
- while (ptr != NULL && ptr->name != id)
- ptr = ptr->blink;
- return ptr;
- }
-
- /*
- * nxt_pre - assign next prefix. A prefix is 2 characters from 0-9 and a-z,
- * at least one of which is numeric.
- *
- * Warning - ascii dependence, must be changed for ebcdic.
- *
- */
- novalue nxt_pre(pre, nxt)
- char *pre;
- char *nxt;
- {
- if (nxt[0] == 'z' + 1) {
- fprintf(stderr, "out of unique prefixes\n");
- exit(ErrorExit);
- }
-
- pre[0] = nxt[0];
- pre[1] = nxt[1];
-
- /*
- * increment next nxtfix.
- */
- if (nxt[1] == '9') {
- if (isdigit(nxt[0]))
- nxt[1] = 'a';
- else {
- if (nxt[0] == '9')
- nxt[0] = 'a';
- else
- ++nxt[0];
- nxt[1] = '0';
- }
- }
- else if (nxt[1] == 'z') {
- if (nxt[0] == '9')
- nxt[0] = 'a';
- else
- ++nxt[0];
- nxt[1] = '0';
- }
- else
- ++nxt[1];
- }
-
- int cmp_pre(pre1, pre2)
- char *pre1;
- char *pre2;
- {
- int cmp;
-
- cmp = cmp_1_pre(pre1[0], pre2[0]);
- if (cmp == 0)
- return cmp_1_pre(pre1[1], pre2[1]);
- else
- return cmp;
- }
-
- static int cmp_1_pre(p1, p2)
- int p1;
- int p2;
- {
- if (isdigit(p1)) {
- if (isdigit(p2))
- return p1 - p2;
- else
- return -1;
- }
- else {
- if (isdigit(p2))
- return 1;
- else
- return p1 - p2;
- }
- }
-
- novalue db_err1(fatal, s)
- int fatal;
- char *s;
- {
- if (fatal)
- fprintf(stderr, "error, ");
- else
- fprintf(stderr, "warning, ");
- fprintf(stderr, "data base \"%s\", line %d - %s\n", dbname, dbline, s);
- if (fatal)
- exit(ErrorExit);
- }
-
- novalue db_err2(fatal, s1, s2)
- int fatal;
- char *s1;
- char *s2;
- {
- if (fatal)
- fprintf(stderr, "error, ");
- else
- fprintf(stderr, "warning, ");
- fprintf(stderr, "data base \"%s\", line %d - %s %s\n", dbname, dbline, s1,
- s2);
- if (fatal)
- exit(ErrorExit);
- }
-
- static novalue db_err3(fatal, s1, s2, s3)
- int fatal;
- char *s1;
- char *s2;
- char *s3;
- {
- if (fatal)
- fprintf(stderr, "error, ");
- else
- fprintf(stderr, "warning, ");
- fprintf(stderr, "data base \"%s\", line %d - %s %s%s\n", dbname, dbline, s1,
- s2, s3);
- if (fatal)
- exit(ErrorExit);
- }
-